DEFINE CLASS FileTimes AS CUSTOM
  * Define constants
  #DEFINE GENERIC_READ  0x80000000
  #DEFINE GENERIC_WRITE 0x40000000
  oConvert = ""
  oFiles = ""
  
  FUNCTION Init
 
    DECLARE SHORT SetFileTime IN Win32API;
      INTEGER hFile, STRING @lpftCreation,;
      STRING @lpftLastAccess, STRING @lpftLastWrite
    DECLARE SHORT GetFileTime IN Win32API;
      INTEGER hFile, STRING @lpftCreation,;
      STRING @lpftLastAccess, STRING @lpftLastWrite
    IF NOT 'CON_TIME' $ SET('PROCEDURE')
      SET PROCEDURE TO CON_TIME ADDITIVE
    ENDIF
    This.oConvert = CREATEOBJECT('ConvertTime')
    RELEASE PROCEDURE CON_TIME
    IF NOT 'FILEIO' $ SET('PROCEDURE')
      SET PROCEDURE TO FILEIO ADDITIVE
    ENDIF
    This.oFiles = CREATEOBJECT("FileOpenClose")
    RETURN NOT ISNULL(This.oConvert)
  ENDPROC
  
  PROCEDURE Error
    
    LPARAMETERS nError, cMethod, nLine
    
    This.oFiles.CloseFile
    RETURN
  ENDPROC
  
  FUNCTION GetFilesTime
    * Retrieves a file's time stamp
 
    LPARAMETERS pcFileName, pdtCreate, pdtAccess, pdtModified
    * The pdt... parameters are optional
    
    LOCAL llresult, ldtCreate, ldtAccess, ldtModified
    STORE REPLICATE(CHR(0), 8) TO ldtCreate, ldtAccess, ldtModified
    llresult = This.oFiles.OpenFile(pcFileName, GENERIC_READ)
    IF llresult
      * Get the time
      = GetFileTime(This.oFiles.nFileHandle, @ldtCreate, @ldtAccess, @ldtModified)
      * Close the file
      This.oFiles.CloseFile
      * Convert to DATETIMEs
      * and store if appropriate
      IF TYPE('pdtCreate') = 'T'
        pdtCreate = This.ConvertFileTime(ldtCreate)
      ENDIF
      * This is for restoring
      ldtAccess = This.ConvertFileTime(ldtAccess)
      IF TYPE('pdtAccess') = 'T'
        pdtAccess = ldtAccess
      ENDIF
      IF TYPE('pdtModified') = 'T'
        pdtModified = This.ConvertFileTime(ldtModified)
      ENDIF
      * Restore the last access time
      This.SetFilesTime(pcFileName, , @ldtAccess, )
    ENDIF
    RETURN llresult
  ENDFUNC
  
  FUNCTION SetFilesTime
  
    LPARAMETERS pcFileName, pdtCreate, pdtAccess, pdtModified
    * The pdt... parameters are optional
    LOCAL llresult, lnflags, ldtCreate, ldtAccess,;
      ldtModified
    * Open the file
    llresult = This.oFiles.OpenFile(pcFileName, GENERIC_WRITE)
    IF llresult
      lnflags = 0
      IF TYPE('pdtCreate') = 'T'
        ldtCreate = This.ConvertDateTime(pdtCreate)
        lnflags = BITSET(lnflags, 0)
      ENDIF
      IF TYPE('pdtAccess') = 'T'
        ldtAccess = This.ConvertDateTime(pdtAccess)
        lnflags = BITSET(lnflags, 1)
      ENDIF
      IF TYPE('pdtModified') = 'T'
        ldtModified = This.ConvertDateTime(pdtModified)
        lnflags = BITSET(lnflags, 2)
      ENDIF
      DO CASE
        CASE lnflags = 1
         llresult = SetFileTime(This.oFiles.nFileHandle, @ldtCreate, 0, 0)
        CASE lnflags = 2
          llresult = SetFileTime(This.oFiles.nFileHandle, 0, @ldtAccess, 0)
        CASE lnflags = 3
          llresult = SetFileTime(This.oFiles.nFileHandle, @ldtCreate, @ldtAccess, 0)
        CASE lnflags = 4
          llresult = SetFileTime(This.oFiles.nFileHandle, 0, 0, @ldtModified)
        CASE lnflags = 5
          llresult = SetFileTime(This.oFiles.nFileHandle, @ldtCreate, 0, @ldtModified)
        CASE lnflags = 6
          llresult = SetFileTime(This.oFiles.nFileHandle, 0, @ldtAccess, @ldtModified)
        CASE lnflags = 7
          llresult = SetFileTime(This.oFiles.nFileHandle, @ldtCreate, @ldtAccess, @ldtModified)
      ENDCASE
      * Close the file
      This.oFiles.CloseFile
    ENDIF
    RETURN llresult
  ENDFUNC
  
  FUNCTION ConvertFileTime
    * Converts a FILETIME based on
    * UTC time to a DATETIME
    LPARAMETER pcfiletile
    
    LOCAL ldtresult
    ldtresult = This.oConvert.FileToLocalTime(pcfiletile)
    ldtresult = This.oConvert.FileTimeToSystem(ldtresult)
    ldtresult = This.oConvert.SystemToDateTime(ldtresult)
    RETURN ldtresult
  ENDFUNC
  
  FUNCTION ConvertDateTime
    * Converts a DATETIME to
    * system FILETIME
    LPARAMETER pdtdatetime
    
    LOCAL lcresult
    lcresult = This.oConvert.SystemToFileTime(pdtdatetime)
    lcresult = This.oConvert.LocalToFileTime(lcresult)
    RETURN lcresult
  ENDFUNC
  
  PROCEDURE Destroy
  
    This.oConvert = .NULL.
    CLEAR DLLS
    RETURN
  ENDPROC
ENDDEFINE